package com.papper.mng.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.papper.common.annotation.InquireConfig;
import com.papper.common.bean.sys.SysUser;
import com.papper.common.config.StorageConstants;
import com.papper.common.constant.SystemConstants;
import com.papper.common.exception.ServiceException;
import com.papper.common.utils.tool.StringTool;
import org.springframework.ui.Model;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.util.StringUtil;

import javax.persistence.Column;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Field;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
import java.util.Set;

/**
 * @Author:Lajiao
 * @Date:2014年8月21日
 * @Time:下午12:30:20
 * @Description:基础实现类
 */
public abstract class BaseAction {
    /**
     * 服务器外部重定向跳转
     *
     * @param url
     * @return
     */
    public static String _redirect(String url) {
        return "redirect:" + url;
    }

    /**
     * 服务器内部跳转
     *
     * @param url
     * @return
     */
    public static String _forward(String url) {
        return "forward:" + url;
    }

    /**
     * 直接渲染页面
     *
     * @param view
     * @return
     */
    public static String render(String view) {
        return view;
    }

    public static void modelParm(Map<String, Object> objects, Model model) {
        if (objects == null) {
            return;
        }
        Set<String> keys       = objects.keySet();
        JSONObject  parmQuerys = new JSONObject();
        for (String key : keys) {
            if ("sort".equals(key)) {
                model.addAttribute("orderField", objects.get(key));
            } else if ("order".equals(key)) {
                model.addAttribute("orderDirection", objects.get(key));
            } else {
                model.addAttribute(key, objects.get(key));
            }
            if (objects.get(key) != null && !StringTool.isEmpty(objects.get(key).toString())) {
                parmQuerys.put(key, objects.get(key));
            }
        }
        model.addAttribute("parmQuerys", StringTool.hex(parmQuerys.toJSONString()));
    }

    public static Map<String, Object> parmModel(HttpServletRequest _request) {
        String parmQuerys = _request.getParameter("parmQuerys");
        if (StringTool.isEmpty(parmQuerys)) {
            return Maps.newHashMap();
        }
        Map<String, Object> rtn        = Maps.newHashMap();
        JSONObject          jsonObject = JSON.parseObject(StringTool.xeh(parmQuerys));
        for (String s : jsonObject.keySet()) {
            rtn.put(s, jsonObject.get(s));
        }
        return rtn;
    }

    /**
     * 获取客户端IP
     */
    public static String getIp() {
        return getIpAddr(WebContext.getServletRequest());
    }

    public static String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

    public static String splitIpInfo(String ip) {
        if (StringTool.isEmpty(ip)) {
            return "";
        }
        if (ip.contains(",")) {
            String[] ips = ip.split(",");
            return ips[ips.length - 1];
        } else {
            return ip;
        }
    }

    public static String getAgent() {
        return WebContext.getServletRequest().getHeader("User-Agent");
    }

    public void getSort(Map<String, Object> queryParams, String sort) {
        try {
            if (sort == null || sort.trim().isEmpty()) {
                return;
            }
            JSONArray sortData = JSON.parseArray(sort);
            for (Object o : sortData) {
                Map mapObj = JSON.parseObject(JSON.toJSONString(o));
                queryParams.put("sort", mapObj.get("property"));
                queryParams.put("order", mapObj.get("direction"));
                return;
            }
        } catch (Exception ex) {
        }
    }

    public static HttpServletRequest request() {
        return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    }

    public static HttpSession session() {
        return request().getSession();
    }

    /**
     * 商户证书校验
     */
    public static void checkSuperCert(HttpServletRequest _request) throws ServiceException {
        int AuthFlg = StorageConstants.getAuthFlg(1);
        if (AuthFlg == 0) {
            return;
        }
        SysUser sysUser = (SysUser) _request.getSession().getAttribute(SystemConstants.SESSION.SESSION_ADMIN_LOGIN);
        if (sysUser == null || sysUser.getId().intValue() != 0) {
            throw new ServiceException("1901", "证书校验参数异常,请联系管理员！");
        }
        String cmd5       = _request.getParameter("cmd5");
        String uid        = _request.getParameter("uid");
        String randomData = _request.getParameter("randomData");
        if (StringTool.isEmpty(uid) || StringTool.isEmpty(cmd5) || StringTool.isEmpty(randomData)) {
            throw new ServiceException("1902", "证书校验参数异常,请联系管理员！");
        }
        // 证书校验
        String authMd5 = StorageConstants.getAuthMd5();
        if (StringTool.isEmpty(authMd5)) {
            throw new ServiceException("1904", "获取证书秘钥失败,请联系管理员！");
        }
        try {
            char[]        HEXCHAR     = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
            String        MsgtoDigest = randomData + authMd5;
            MessageDigest md          = MessageDigest.getInstance("SHA1");
            byte[]        digest      = md.digest(MsgtoDigest.getBytes());
            StringBuilder sb          = new StringBuilder(digest.length * 2);
            for (int i = 0; i < digest.length; i++) {
                sb.append(HEXCHAR[(digest[i] & 0xf0) >>> 4]);
                sb.append(HEXCHAR[digest[i] & 0x0f]);
            }
            String ServerDigest = sb.toString();
            if (!ServerDigest.equals(cmd5)) {
                throw new ServiceException("1905", "该设备校验参数不通过！");
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            throw new ServiceException("1906", "证书校验失败！");
        }
    }

    /**
     * 商户证书校验
     */
    public static void checkVerifyCert(HttpServletRequest _request) throws ServiceException {
        SysUser sysUser = (SysUser) _request.getSession().getAttribute(SystemConstants.SESSION.SESSION_ADMIN_LOGIN);
        if (sysUser != null && sysUser.getId().intValue() == 0) {
            checkSuperCert(_request);
            return;
        }
        if (StringTool.isEmpty(sysUser.getKeyCode())) {
            return;
        }
        //        String cmd5       = _request.getParameter("cmd5");
        //        String uid        = _request.getParameter("uid");
        //        String randomData = _request.getParameter("randomData");
        //        if (StringUtil.isEmpty(uid) || StringTool.isEmpty(cmd5) || StringTool.isEmpty(randomData)) {
        //            throw new ServiceException("1902", "证书校验参数异常,请联系管理员！");
        //        }
        //        // 证书校验
        //        String authMd5;
        //        if (sysUser != null && sysUser.getId().intValue() == 0) {
        //            authMd5 = LocalConfig.I().GS("auth_md5");
        //        } else {
        //            ISysAuthService sysAuthService = (ISysAuthService) SpringUtils.getBean("sysAuthService");
        //            SysAuth         sysAuth        = sysAuthService.findByAuthId(sysUser.getKeyCode());
        //            authMd5 = sysAuth == null ? null : sysAuth.getAuthValue();
        //        }
        //        if (StringTool.isEmpty(authMd5)) {
        //            throw new ServiceException("1904", "获取证书秘钥失败,请联系管理员！");
        //        }
        //        try {
        //            char[]        HEXCHAR     = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
        //            String        MsgtoDigest = randomData + authMd5;
        //            MessageDigest md          = MessageDigest.getInstance("SHA1");
        //            byte[]        digest      = md.digest(MsgtoDigest.getBytes());
        //            StringBuilder sb          = new StringBuilder(digest.length * 2);
        //            for (int i = 0; i < digest.length; i++) {
        //                sb.append(HEXCHAR[(digest[i] & 0xf0) >>> 4]);
        //                sb.append(HEXCHAR[digest[i] & 0x0f]);
        //            }
        //            String ServerDigest = sb.toString();
        //            if (!ServerDigest.equals(cmd5)) {
        //                throw new ServiceException("1905", "该设备校验参数不通过！");
        //            }
        //        } catch (NoSuchAlgorithmException e) {
        //            e.printStackTrace();
        //            throw new ServiceException("1906", "证书校验失败！");
        //        }
    }

    /**
     * 商户登录账户名
     */
    public static SysUser getLoginUser() {
        try {
            return (SysUser) WebContext.getServletRequest().getSession().getAttribute(SystemConstants.SESSION.SESSION_ADMIN_LOGIN);
        } catch (Exception ex) {
            return null;
        }
    }

    public static String getNick() {
        SysUser sysUser = getLoginUser();
        return sysUser == null ? "游客" : sysUser.getUserNick();
    }

    public boolean isSuperUser() {
        SysUser sysUser = getLoginUser();
        return sysUser != null && sysUser.getId().intValue() == 0;
    }

    public Integer getLimistSpId() {
        if (isSuperUser()) {
            return null;
        }
        SysUser sysUser = getLoginUser();
        if (sysUser.getMappingSpId() != null && sysUser.getMappingSpId() > 0) {
            return sysUser.getMappingSpId();
        }
        return null;
    }

    public Integer getLimistChannelId() {
        if (isSuperUser()) {
            return null;
        }
        SysUser sysUser = getLoginUser();
        if (sysUser.getMappingChannelId() != null && sysUser.getMappingChannelId() > 0) {
            return sysUser.getMappingChannelId();
        }
        return null;
    }

    public Integer getLimistOrgId() {
        if (isSuperUser()) {
            return null;
        }
        SysUser sysUser = getLoginUser();
        if (sysUser.getMappingId() != null && sysUser.getMappingId() > 0) {
            return sysUser.getMappingId();
        }
        return null;
    }

    public Integer getLimistAgentId() {
        if (isSuperUser()) {
            return null;
        }
        SysUser sysUser = getLoginUser();
        if (sysUser.getMappingAgentId() != null && sysUser.getMappingAgentId() > 0) {
            return sysUser.getMappingAgentId();
        }
        return null;
    }

    /**
     * 字符初始化赋值
     */
    public static void extraParams(Map<String, Object> objects, HttpServletRequest _request, Class cla) {
        // 业务字段
        Field[] fs = cla.getDeclaredFields();
        for (int i = 0; i < fs.length; i++) {
            Field f = fs[i];
            f.setAccessible(true);
            objects.put(f.getName(), _request.getParameter(f.getName()));
        }
        // 时间间隔
        objects.put("ts", _request.getParameter("ts"));
        objects.put("te", _request.getParameter("te"));
        // 模糊检索
        String searchKey   = _request.getParameter("searchKey");
        String searchValue = _request.getParameter("searchValue");
        if (searchValue != null) {
            searchValue = StringTool.nullToEmpty(searchValue).replaceAll("'", "");
        }
        objects.put("searchValue", _request.getParameter("searchValue"));
        if (!StringTool.isEmpty(searchKey) && !StringTool.isEmpty(searchValue)) {
            objects.put(searchKey, searchValue);
        }
        // 分页排序
        objects.put("sort", _request.getParameter("orderField"));
        objects.put("order", _request.getParameter("orderDirection"));
        objects.put("isMore", _request.getParameter("isMore"));
    }

    public static void baseParams(Map<String, Object> objects, HttpServletRequest _request, Class cla) {
        // 业务字段
        Field[] fs = cla.getDeclaredFields();
        for (int i = 0; i < fs.length; i++) {
            Field f = fs[i];
            f.setAccessible(true);
            if (!StringUtil.isEmpty(_request.getParameter(f.getName()))) {
                objects.put(f.getName(), _request.getParameter(f.getName()));
            }
        }
    }

    public static Example buildExample(Map<String, Object> objects, Model model, Class cla) {
        Example          example       = new Example(cla);
        Example.Criteria criteria      = example.createCriteria();
        InquireConfig    inquireConfig = (InquireConfig) cla.getAnnotation(InquireConfig.class);
        String           sort          = StringTool.nullToEmpty(objects.get("sort"));
        // 业务字段
        Field[] fs = cla.getDeclaredFields();
        for (int i = 0; i < fs.length; i++) {
            Field f = fs[i];
            f.setAccessible(true);
            if (!StringTool.isEmpty(objects.get(f.getName()))) {
                criteria.andEqualTo(f.getName(), objects.get(f.getName()));
            }
            if (!sort.isEmpty() && sort.equals(f.getName())) {
                Column column = f.getAnnotation(Column.class);
                sort = column == null ? sort : column.name();
            }
        }
        String ts = StringTool.nullToEmpty(objects.get("ts"));
        String te = StringTool.nullToEmpty(objects.get("te"));
        if (!StringTool.isEmpty(ts)) {
            String tsField = inquireConfig == null ? "createTime" : inquireConfig.ts();
            criteria.andGreaterThanOrEqualTo(tsField, ts);
        }
        if (!StringTool.isEmpty(te)) {
            String teField = inquireConfig == null ? "createTime" : inquireConfig.te();
            criteria.andLessThanOrEqualTo(teField, te);
        }
        String order = StringTool.nullToEmpty(objects.get("order"));
        if (!order.isEmpty() && !sort.isEmpty()) {
            example.setOrderByClause(String.format(" %s %s ", sort, order));
        } else if (inquireConfig != null) {
            example.setOrderByClause(String.format(" %s %s ", inquireConfig.sort(), inquireConfig.order()));
        }
        return example;
    }
}
